// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <FileConnection.h>

// *******************************************************************
// Method: FileConnection::FileConnection
//
// Purpose: 
//   Constructor for the FileConnection class.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:15:46 PST 2000
//
// Modifications:
//   Brad Whitlock, Wed Mar 20 17:35:48 PST 2002
//   Moved the contents of the old Open method here.
//
// *******************************************************************

FileConnection::FileConnection(const char *filename, bool writeMode_) :
    Connection()
{
    fileStream = 0;
    fileSize = 0;
    writeMode = writeMode_;

    if(writeMode)
    {
        fileStream = fopen(filename, "wb");

        // Write out the type information for this end
        Write(srcFormat.Format);
        Write(srcFormat.IntFormat);
        Write(srcFormat.LongFormat);
        Write(srcFormat.FloatFormat);
        Write(srcFormat.DoubleFormat);

        fileSize = 0;
    }
    else
    {
        fileStream = fopen(filename, "rb");

        // Read the type information for the other end
        Read(&destFormat.Format);
        Read(&destFormat.IntFormat);
        Read(&destFormat.LongFormat);
        Read(&destFormat.FloatFormat);
        Read(&destFormat.DoubleFormat);

        fileSize = 100; // Get the size of the input file.
    }
}

// *******************************************************************
// Method: FileConnection::~FileConnection
//
// Purpose: 
//   Destructor for the FileConnection class.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:16:22 PST 2000
//
// Modifications:
//   
// *******************************************************************

FileConnection::~FileConnection()
{
    if(fileStream != 0)
    {
        fclose(fileStream);
        fileStream = 0;
    }
}

// ****************************************************************************
// Method: FileConnection::Fill
//
// Purpose: 
//   Tries to fill the connection with data.
//
// Returns:    The number of bytes that were filled.
//
// Programmer: Brad Whitlock
// Creation:   Wed Mar 20 17:37:11 PST 2002
//
// Modifications:
//   
// ****************************************************************************

int
FileConnection::Fill()
{
    return 0;
}

// *******************************************************************
// Method: FileConnection::Flush
//
// Purpose: 
//   Flushes the connection. In this case, it writes remaining
//   characters to the file.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:20:07 PST 2000
//
// Modifications:
//   
// *******************************************************************

void
FileConnection::Flush()
{
    if(fileStream == 0)
        return;

    fflush(fileStream);
}

// *******************************************************************
// Method: FileConnection::Write
//
// Purpose: 
//   Writes a character to the file.
//
// Arguments:
//   value : The character to write.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:20:54 PST 2000
//
// Modifications:
//   
// *******************************************************************

void
FileConnection::Write(unsigned char value)
{
    fputc(value, fileStream);
    ++fileSize;
}

// *******************************************************************
// Method: FileConnection::Read
//
// Purpose: 
//   Reads a character from the file.
//
// Arguments:
//   address : The address of the variable into which we'll put the char.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:21:27 PST 2000
//
// Modifications:
//   
// *******************************************************************

void
FileConnection::Read(unsigned char *address)
{
    *address = (unsigned char)fgetc(fileStream);
    --fileSize;
}

// *******************************************************************
// Method: FileConnection::Size
//
// Purpose: 
//   Returns the number of characters that have not been read.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:22:18 PST 2000
//
// Modifications:
//   
// *******************************************************************

long
FileConnection::Size()
{
    return fileSize;
}

// *******************************************************************
// Method: FileConnection::Append
//
// Purpose: 
//   Writes a block of characters to the file.
//
// Arguments:
//   address : The array of characters to write to the file.
//   nChars  : The length of the character array.
//
// Programmer: Brad Whitlock
// Creation:   Thu Oct 5 14:23:09 PST 2000
//
// Modifications:
//   
// *******************************************************************

void
FileConnection::Append(const unsigned char *address, int nChars)
{
    if(writeMode)
    {
        fwrite((void *)address, 1, nChars, fileStream);
        fileSize += nChars;
    }
}

// ****************************************************************************
// Method: FileConnection::DirectRead
//
// Purpose: 
//   Reads the specified number of bytes from the connection.
//
// Arguments:
//   buf    : The destination buffer.
//   ntotal : The number of bytes to read.
//
// Returns:    The number of bytes read.
//
// Programmer: Brad Whitlock
// Creation:   Mon Mar 25 14:28:39 PST 2002
//
// Modifications:
//   
// ****************************************************************************

long
FileConnection::DirectRead(unsigned char *buf, long len)
{
    long retval = 0;

    if(!writeMode)
    {
         retval = (long)fread((void *)buf, len, 1, fileStream);
    }

    return retval;
}

// ****************************************************************************
// Method: FileConnection::DirectWrite
//
// Purpose: 
//   Writes a buffer to the connection without doing any buffering.
//
// Arguments:
//   buf    : The buffer that we want to write.
//   ntotal : The length of the buffer.
//
// Returns:    The number of bytes written.
//
// Note:       This method was adapted from Jeremy's write_n function.
//
// Programmer: Brad Whitlock
// Creation:   Mon Mar 25 14:33:40 PST 2002
//
// Modifications:
//   
// ****************************************************************************

long
FileConnection::DirectWrite(const unsigned char *buf, long len)
{
    long retval = 0;

    if(writeMode)
    {
         retval = (long)fwrite((const void *)buf, len, 1, fileStream);
    }

    return retval;
}
